home *** CD-ROM | disk | FTP | other *** search
/ Aminet 23 / Aminet 23 (1998)(GTI - Schatztruhe)[!][Feb 1998].iso / Aminet / misc / emu / amiSPIMsrc.lha / run.c < prev    next >
C/C++ Source or Header  |  1994-01-17  |  26KB  |  1,184 lines

  1. /* SPIM S20 MIPS simulator.
  2.    Execute SPIM instructions.
  3.    Copyright (C) 1990-1994 by James Larus (larus@cs.wisc.edu).
  4.    ALL RIGHTS RESERVED.
  5.  
  6.    SPIM is distributed under the following conditions:
  7.  
  8.      You may make copies of SPIM for your own use and modify those copies.
  9.  
  10.      All copies of SPIM must retain my name and copyright notice.
  11.  
  12.      You may not sell SPIM or distributed SPIM in conjunction with a
  13.      commerical product or service without the expressed written consent of
  14.      James Larus.
  15.  
  16.    THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  17.    IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  18.    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  19.    PURPOSE. */
  20.  
  21.  
  22. /* $Header: /home/primost/larus/Software/SPIM/RCS/run.c,v 3.37 1994/01/18 03:21:45 larus Exp larus $
  23. */
  24.  
  25.  
  26. #ifdef mips
  27. #define _IEEE 1
  28. #include <nan.h>
  29. #else
  30. #define NaN(X) 0
  31. #endif
  32.  
  33. #include <math.h>
  34. #include <stdio.h>
  35.  
  36. #include "spim.h"
  37. #include "spim-utils.h"
  38. #include "inst.h"
  39. #include "mem.h"
  40. #include "reg.h"
  41. #include "sym-tbl.h"
  42. #include "y.tab.h"
  43. #include "read-aout.h"
  44. #include "mips-syscall.h"
  45. #include "run.h"
  46.  
  47.  
  48. extern int errno;
  49.  
  50. #ifdef __STDC__
  51. long atol (const char *);
  52. #else
  53. long atol ();
  54. #endif
  55.  
  56.  
  57. /* Local functions: */
  58.  
  59. #ifdef __STDC__
  60. static void long_multiply (reg_word v1, reg_word v2);
  61. #else
  62. static void long_multiply ();
  63. #endif
  64.  
  65.  
  66. #define SIGN_BIT(X) ((X) & 0x80000000)
  67.  
  68. #define ARITH_OVFL(RESULT, OP1, OP2) (SIGN_BIT (OP1) == SIGN_BIT (OP2) \
  69.                       && SIGN_BIT (OP1) != SIGN_BIT (RESULT))
  70.  
  71.  
  72. /* Executed delayed branch and jump instructions by running the
  73.    instruction from the delay slot before transfering control.  Note,
  74.    in branches that don't jump, the instruction in the delay slot is
  75.    executed by falling through normally.
  76.  
  77.    We take advantage of the MIPS architecture, which leaves undefined
  78.    the result of executing a delayed instruction in a delay slot.  Here
  79.    we execute the second branch. */
  80.  
  81. #define BRANCH_INST(TEST, TARGET) {if (TEST)                \
  82.                     {                    \
  83.                       mem_addr target = (TARGET);    \
  84.                       if (bare_machine)            \
  85.                     /* +4 since jump in delay slot */\
  86.                     target += BYTES_PER_WORD;    \
  87.                       JUMP_INST (target)        \
  88.                     }                    \
  89.                   }
  90.  
  91.  
  92. #define JUMP_INST(TARGET) {if (bare_machine)                \
  93.                 run_spim (PC + BYTES_PER_WORD, 1, display);    \
  94.               /* -4 since PC is bumped after this inst */    \
  95.               PC = (TARGET) - BYTES_PER_WORD;        \
  96.               }
  97.  
  98.  
  99. /* Result from load is available immediate, but no program should ever have
  100.    assumed otherwise because of exceptions.*/
  101.  
  102. #define LOAD_INST(OP, ADDR, DEST_A, MASK)                \
  103.                  {reg_word tmp;                \
  104.                    OP (tmp, (ADDR));            \
  105.                    *(DEST_A) = tmp & (MASK);        \
  106.                  }
  107.  
  108.  
  109. #define DELAYED_UPDATE(A, D) {if (delayed_addr1 != NULL)        \
  110.                 fatal_error("Two calls to DELAYED_UPDATE\n");\
  111.                 delayed_addr1 = A; delayed_value1 = D;    \
  112.                   }
  113.  
  114.  
  115. #define DO_DELAYED_UPDATE() if (bare_machine)                \
  116.                    {                    \
  117.                  /* Check for delayed updates */    \
  118.                  if (delayed_addr2 != NULL)        \
  119.                    *delayed_addr2 = delayed_value2;    \
  120.                  delayed_addr2 = delayed_addr1;        \
  121.                  delayed_value2 = delayed_value1;    \
  122.                  delayed_addr1 = NULL;            \
  123.                    }
  124.  
  125.  
  126.  
  127. /* Run the program stored in memory, starting at address PC for
  128.    STEPS_TO_RUN instruction executions.  If flag DISPLAY is non-zero, print
  129.    each instruction before it executes. Return non-zero if program's
  130.    execution can continue. */
  131.  
  132.  
  133. #ifdef __STDC__
  134. int
  135. run_spim (mem_addr initial_PC, int steps_to_run, int display)
  136. #else
  137. int
  138. run_spim (initial_PC, steps_to_run, display)
  139.      mem_addr initial_PC;
  140.      int steps_to_run;
  141.      int display;
  142. #endif
  143. {
  144.   register instruction *inst;
  145.   static reg_word *delayed_addr1 = NULL, delayed_value1;
  146.   static reg_word *delayed_addr2 = NULL, delayed_value2;
  147.   int step, step_size, next_step;
  148.  
  149.   PC = initial_PC;
  150.   if (!bare_machine && mapped_io)
  151.     next_step = IO_INTERVAL;
  152.   else
  153.     next_step = steps_to_run;    /* Run to completion */
  154.  
  155.   for (step_size = MIN (next_step, steps_to_run);
  156.        steps_to_run > 0;
  157.        steps_to_run -= step_size, step_size = MIN (next_step, steps_to_run))
  158.     {
  159.       if (!bare_machine && mapped_io)
  160.     /* Every IO_INTERVAL steps, check if memory-mapped IO registers
  161.        have changed. */
  162.     check_memory_mapped_IO ();
  163.       /* else run inner loop for all steps */
  164.  
  165.       for (step = 0; step < step_size; step += 1)
  166.     {
  167.  
  168.       R[0] = 0;        /* Maintain invariant value */
  169.  
  170.       READ_MEM_INST (inst, PC);
  171.  
  172.       if (exception_occurred)
  173.         {
  174.           exception_occurred = 0;
  175.           EPC = PC & 0xfffffffc; /* Round down */
  176.           handle_exception();
  177.           continue;
  178.         }
  179.       else if (inst == NULL)
  180.         run_error ("Attempt to execute non-instruction at 0x%08x\n", PC);
  181.       else if (EXPR (inst) != NULL
  182.            && EXPR (inst)->symbol != NULL
  183.            && EXPR (inst)->symbol->addr == 0)
  184.         {
  185.           error ("Instruction references undefined symbol at 0x%08x\n",
  186.              PC);
  187.           print_inst (PC);
  188.           run_error ("");
  189.         }
  190.  
  191.       if (display)
  192.         print_inst (PC);
  193.  
  194. #ifdef TEST_ASM
  195.       test_assembly (inst);
  196. #endif
  197.  
  198.       DO_DELAYED_UPDATE ();
  199.  
  200.       switch (OPCODE (inst))
  201.         {
  202.         case Y_ADD_OP:
  203.           {
  204.         register reg_word vs = R[RS (inst)], vt = R[RT (inst)];
  205.         register reg_word sum = vs + vt;
  206.  
  207.         if (ARITH_OVFL (sum, vs, vt))
  208.           RAISE_EXCEPTION (OVF_EXCPT, break);
  209.         R[RD (inst)] = sum;
  210.         break;
  211.           }
  212.  
  213.         case Y_ADDI_OP:
  214.           {
  215.         register reg_word vs = R[RS (inst)], imm = (short) IMM (inst);
  216.         register reg_word sum = vs + imm;
  217.  
  218.         if (ARITH_OVFL (sum, vs, imm))
  219.           RAISE_EXCEPTION (OVF_EXCPT, break);
  220.         R[RT (inst)] = sum;
  221.         break;
  222.           }
  223.  
  224.         case Y_ADDIU_OP:
  225.           R[RT (inst)] = R[RS (inst)] + (short) IMM (inst);
  226.           break;
  227.  
  228.         case Y_ADDU_OP:
  229.           R[RD (inst)] = R[RS (inst)] + R[RT (inst)];
  230.           break;
  231.  
  232.         case Y_AND_OP:
  233.           R[RD (inst)] = R[RS (inst)] & R[RT (inst)];
  234.           break;
  235.  
  236.         case Y_ANDI_OP:
  237.           R[RT (inst)] = R[RS (inst)] & (0xffff & IMM (inst));
  238.           break;
  239.  
  240.         case Y_BC0F_OP:
  241.         case Y_BC2F_OP:
  242.         case Y_BC3F_OP:
  243.           BRANCH_INST (CpCond[OPCODE (inst) - Y_BC0F_OP] == 0,
  244.                PC + (SIGN_EX (IOFFSET (inst)) << 2));
  245.           break;
  246.  
  247.         case Y_BC0T_OP:
  248.         case Y_BC2T_OP:
  249.         case Y_BC3T_OP:
  250.           BRANCH_INST (CpCond[OPCODE (inst) - Y_BC0T_OP] != 0,
  251.                PC + (SIGN_EX (IOFFSET (inst)) << 2));
  252.           break;
  253.  
  254.         case Y_BEQ_OP:
  255.           BRANCH_INST (R[RS (inst)] == R[RT (inst)],
  256.                PC + (SIGN_EX (IOFFSET (inst)) << 2));
  257.           break;
  258.  
  259.         case Y_BGEZ_OP:
  260.           BRANCH_INST (SIGN_BIT (R[RS (inst)]) == 0,
  261.                PC + (SIGN_EX (IOFFSET (inst)) << 2));
  262.           break;
  263.  
  264.         case Y_BGEZAL_OP:
  265.           if (bare_machine)
  266.         R[31] = PC + 2 * BYTES_PER_WORD;
  267.           else
  268.         R[31] = PC + BYTES_PER_WORD;
  269.           BRANCH_INST (SIGN_BIT (R[RS (inst)]) == 0,
  270.                PC + (SIGN_EX (IOFFSET (inst)) << 2));
  271.           break;
  272.  
  273.         case Y_BGTZ_OP:
  274.           BRANCH_INST (R[RS (inst)] != 0 && SIGN_BIT (R[RS (inst)]) == 0,
  275.                PC + (SIGN_EX (IOFFSET (inst)) << 2));
  276.           break;
  277.  
  278.         case Y_BLEZ_OP:
  279.           BRANCH_INST (R[RS (inst)] == 0 || SIGN_BIT (R[RS (inst)]) != 0,
  280.                PC + (SIGN_EX (IOFFSET (inst)) << 2));
  281.           break;
  282.  
  283.         case Y_BLTZ_OP:
  284.           BRANCH_INST (SIGN_BIT (R[RS (inst)]) != 0,
  285.                PC + (SIGN_EX (IOFFSET (inst)) << 2));
  286.           break;
  287.  
  288.         case Y_BLTZAL_OP:
  289.           if (bare_machine)
  290.         R[31] = PC + 2 * BYTES_PER_WORD;
  291.           else
  292.         R[31] = PC + BYTES_PER_WORD;
  293.           BRANCH_INST (SIGN_BIT (R[RS (inst)]) != 0,
  294.                PC + (SIGN_EX (IOFFSET (inst)) << 2));
  295.           break;
  296.  
  297.         case Y_BNE_OP:
  298.           BRANCH_INST (R[RS (inst)] != R[RT (inst)],
  299.                PC + (SIGN_EX (IOFFSET (inst)) << 2));
  300.           break;
  301.  
  302.         case Y_BREAK_OP:
  303.           if (RD (inst) == 1)
  304.         /* Debugger breakpoint */
  305.         RAISE_EXCEPTION (BKPT_EXCPT, return (1))
  306.           else
  307.         RAISE_EXCEPTION (BKPT_EXCPT, break);
  308.  
  309.         case Y_CFC0_OP:
  310.         case Y_CFC2_OP:
  311.         case Y_CFC3_OP:
  312.           R[RT (inst)] = CCR[OPCODE (inst) - Y_CFC0_OP][RD (inst)];
  313.           break;
  314.  
  315.         case Y_COP0_OP:
  316.         case Y_COP1_OP:
  317.         case Y_COP2_OP:
  318.         case Y_COP3_OP:
  319.           CCR[OPCODE (inst) - Y_COP0_OP][RD (inst)] = R[RT (inst)];
  320.           break;
  321.  
  322.         case Y_CTC0_OP:
  323.         case Y_CTC2_OP:
  324.         case Y_CTC3_OP:
  325.           CCR[OPCODE (inst) - Y_CTC0_OP][RD (inst)] = R[RT (inst)];
  326.           break;
  327.  
  328.         case Y_DIV_OP:
  329.           if (R[RT (inst)] != 0)
  330.         {
  331.           LO = (long) R[RS (inst)] / (long) R[RT (inst)];
  332.           HI = (long) R[RS (inst)] % (long) R[RT (inst)];
  333.         }
  334.           break;
  335.  
  336.         case Y_DIVU_OP:
  337.           if (R[RT (inst)] != 0)
  338.         {
  339.           LO = ((unsigned long) R[RS (inst)]
  340.                 / (unsigned long) R[RT (inst)]);
  341.           HI = ((unsigned long) R[RS (inst)]
  342.             % (unsigned long) R[RT (inst)]);
  343.         }
  344.           break;
  345.  
  346.         case Y_J_OP:
  347.           JUMP_INST (((PC & 0xf0000000) | TARGET (inst) << 2));
  348.           break;
  349.  
  350.         case Y_JAL_OP:
  351.           if (bare_machine)
  352.         R[31] = PC + 2 * BYTES_PER_WORD;
  353.           else
  354.         R[31] = PC + BYTES_PER_WORD;
  355.           JUMP_INST (((PC & 0xf0000000) | (TARGET (inst) << 2)));
  356.           break;
  357.  
  358.         case Y_JALR_OP:
  359.           {
  360.         mem_addr tmp = R[RS (inst)];
  361.  
  362.         if (bare_machine)
  363.           R[RD (inst)] = PC + 2 * BYTES_PER_WORD;
  364.         else
  365.           R[RD (inst)] = PC + BYTES_PER_WORD;
  366.         JUMP_INST (tmp);
  367.           }
  368.           break;
  369.  
  370.         case Y_JR_OP:
  371.           {
  372.         mem_addr tmp = R[RS (inst)];
  373.  
  374.         JUMP_INST (tmp);
  375.           }
  376.           break;
  377.  
  378.         case Y_LB_OP:
  379.           LOAD_INST (READ_MEM_BYTE, R[BASE (inst)] + IOFFSET (inst),
  380.              &R[RT (inst)], 0xffffffff);
  381.           break;
  382.  
  383.         case Y_LBU_OP:
  384.           LOAD_INST (READ_MEM_BYTE, R[BASE (inst)] + IOFFSET (inst),
  385.              &R[RT (inst)], 0xff);
  386.           break;
  387.  
  388.         case Y_LH_OP:
  389.           LOAD_INST (READ_MEM_HALF, R[BASE (inst)] + IOFFSET (inst),
  390.              &R[RT (inst)], 0xffffffff);
  391.           break;
  392.  
  393.         case Y_LHU_OP:
  394.           LOAD_INST (READ_MEM_HALF, R[BASE (inst)] + IOFFSET (inst),
  395.              &R[RT (inst)], 0xffff);
  396.           break;
  397.  
  398.         case Y_LUI_OP:
  399.           R[RT (inst)] = (IMM (inst) << 16) & 0xffff0000;
  400.           break;
  401.  
  402.         case Y_LW_OP:
  403.           LOAD_INST (READ_MEM_WORD, R[BASE (inst)] + IOFFSET (inst),
  404.              &R[RT (inst)], 0xffffffff);
  405.           break;
  406.  
  407.         case Y_LWC0_OP:
  408.         case Y_LWC2_OP:
  409.         case Y_LWC3_OP:
  410.           LOAD_INST (READ_MEM_WORD, R[BASE (inst)] + IOFFSET (inst),
  411.              &CPR[OPCODE (inst) - Y_LWC0_OP][RT (inst)],
  412.              0xffffffff);
  413.           break;
  414.  
  415.         case Y_LWL_OP:
  416.           {
  417.         register mem_addr addr = R[BASE (inst)] + IOFFSET (inst);
  418.         reg_word word;    /* Can't be register */
  419.         register int byte = addr & 0x3;
  420.         reg_word reg_val = R[RT (inst)];
  421.  
  422.         LOAD_INST (READ_MEM_WORD, addr & 0xfffffffc, &word,
  423.                0xffffffff);
  424.         DO_DELAYED_UPDATE ();
  425.  
  426.         if ((!exception_occurred) || ((Cause >> 2) > LAST_REAL_EXCEPT))
  427. #ifdef BIGENDIAN
  428.           switch (byte)
  429.             {
  430.             case 0:
  431.               R[RT (inst)] = word;
  432.               break;
  433.  
  434.             case 1:
  435.               R[RT (inst)] = (word & 0xffffff) << 8 | (reg_val & 0xff);
  436.               break;
  437.  
  438.             case 2:
  439.               R[RT (inst)] = (word & 0xffff) << 16 | (reg_val & 0xffff);
  440.               break;
  441.  
  442.             case 3:
  443.               R[RT (inst)] = (word & 0xff) << 24 | (reg_val & 0xffffff);
  444.               break;
  445.             }
  446. #else
  447.         switch (byte)
  448.           {
  449.           case 0:
  450.             R[RT (inst)] = (word & 0xff) << 24 | (reg_val & 0xffffff);
  451.             break;
  452.  
  453.           case 1:
  454.             R[RT (inst)] = (word & 0xffff) << 16 | (reg_val & 0xffff);
  455.             break;
  456.  
  457.           case 2:
  458.             R[RT (inst)] = (word & 0xffffff) << 8 | (reg_val & 0xff);
  459.             break;
  460.  
  461.           case 3:
  462.             R[RT (inst)] = word;
  463.             break;
  464.           }
  465. #endif
  466.         break;
  467.           }
  468.  
  469.         case Y_LWR_OP:
  470.           {
  471.         register mem_addr addr = R[BASE (inst)] + IOFFSET (inst);
  472.         reg_word word;    /* Can't be register */
  473.         register int byte = addr & 0x3;
  474.         reg_word reg_val = R[RT (inst)];
  475.  
  476.         LOAD_INST (READ_MEM_WORD, addr & 0xfffffffc, &word, 0xffffffff);
  477.         DO_DELAYED_UPDATE ();
  478.  
  479.         if ((!exception_occurred) || ((Cause >> 2) > LAST_REAL_EXCEPT))
  480. #ifdef BIGENDIAN
  481.           switch (byte)
  482.             {
  483.             case 0:
  484.               R[RT (inst)] = (reg_val & 0xffffff00)
  485.             | ((word & 0xff000000) >> 24);
  486.               break;
  487.  
  488.             case 1:
  489.               R[RT (inst)] = (reg_val & 0xffff0000)
  490.             | ((word & 0xffff0000) >> 16);
  491.               break;
  492.  
  493.             case 2:
  494.               R[RT (inst)] = (reg_val & 0xff000000)
  495.             | ((word & 0xffffff00) >> 8);
  496.               break;
  497.  
  498.             case 3:
  499.               R[RT (inst)] = word;
  500.               break;
  501.             }
  502. #else
  503.         switch (byte)
  504.           {
  505.             /* NB: The description of the little-endian case in Kane is
  506.                totally wrong. */
  507.           case 0:    /* 3 in book */
  508.             R[RT (inst)] = word;
  509.             break;
  510.  
  511.           case 1:    /* 0 in book */
  512.             R[RT (inst)] = (reg_val & 0xff000000)
  513.               | ((word & 0xffffff00) >> 8);
  514.             break;
  515.  
  516.           case 2:    /* 1 in book */
  517.             R[RT (inst)] = (reg_val & 0xffff0000)
  518.               | ((word & 0xffff0000) >> 16);
  519.             break;
  520.  
  521.           case 3:    /* 2 in book */
  522.             R[RT (inst)] = (reg_val & 0xffffff00)
  523.               | ((word & 0xff000000) >> 24);
  524.             break;
  525.           }
  526. #endif
  527.         break;
  528.           }
  529.  
  530.         case Y_MFC0_OP:
  531.         case Y_MFC2_OP:
  532.         case Y_MFC3_OP:
  533.           R[RT (inst)] = CPR[OPCODE (inst) - Y_MFC0_OP][RD (inst)];
  534.           break;
  535.  
  536.         case Y_MFHI_OP:
  537.           R[RD (inst)] = HI;
  538.           break;
  539.  
  540.         case Y_MFLO_OP:
  541.           R[RD (inst)] = LO;
  542.           break;
  543.  
  544.         case Y_MTC0_OP:
  545.         case Y_MTC2_OP:
  546.         case Y_MTC3_OP:
  547.           CPR[OPCODE (inst) - Y_MTC0_OP][RD (inst)] = R[RT (inst)];
  548.           break;
  549.  
  550.         case Y_MTHI_OP:
  551.           HI = R[RS (inst)];
  552.           break;
  553.  
  554.         case Y_MTLO_OP:
  555.           LO = R[RS (inst)];
  556.           break;
  557.  
  558.         case Y_MULT_OP:
  559.           {
  560.         reg_word v1 = R[RS (inst)], v2 = R[RT (inst)];
  561.         int neg_sign = 0;
  562.  
  563.         if (v1 < 0)
  564.           v1 = - v1, neg_sign = 1;
  565.         if (v2 < 0)
  566.           v2 = - v2, neg_sign = ! neg_sign;
  567.  
  568.         long_multiply (v1, v2);
  569.         if (neg_sign)
  570.           {
  571.             LO = ~ LO;
  572.             HI = ~ HI;
  573.             LO += 1;
  574.             if (LO == 0)
  575.               HI += 1;
  576.           }
  577.           }
  578.           break;
  579.  
  580.         case Y_MULTU_OP:
  581.           long_multiply (R[RS (inst)], R[RT (inst)]);
  582.           break;
  583.  
  584.         case Y_NOR_OP:
  585.           R[RD (inst)] = ~ (R[RS (inst)] | R[RT (inst)]);
  586.           break;
  587.  
  588.         case Y_OR_OP:
  589.           R[RD (inst)] = R[RS (inst)] | R[RT (inst)];
  590.           break;
  591.  
  592.         case Y_ORI_OP:
  593.           R[RT (inst)] = R[RS (inst)] | (0xffff & IMM (inst));
  594.           break;
  595.  
  596.         case Y_RFE_OP:
  597.           Status_Reg = (Status_Reg & 0xfffffff0) | ((Status_Reg & 0x3c) >> 2);
  598.           break;
  599.  
  600.         case Y_SB_OP:
  601.           SET_MEM_BYTE (R[BASE (inst)] + IOFFSET (inst), R[RT (inst)]);
  602.           break;
  603.  
  604.         case Y_SH_OP:
  605.           SET_MEM_HALF (R[BASE (inst)] + IOFFSET (inst), R[RT (inst)]);
  606.           break;
  607.  
  608.         case Y_SLL_OP:
  609.           {
  610.         int shamt = SHAMT (inst);
  611.  
  612.         if (shamt >= 0 && shamt < 32)
  613.           R[RD (inst)] = R[RT (inst)] << shamt;
  614.         else
  615.           R[RD (inst)] = R[RT (inst)];
  616.         break;
  617.           }
  618.  
  619.         case Y_SLLV_OP:
  620.           {
  621.         int shamt = (R[RS (inst)] & 0x1f);
  622.  
  623.         if (shamt >= 0 && shamt < 32)
  624.           R[RD (inst)] = R[RT (inst)] << shamt;
  625.         else
  626.           R[RD (inst)] = R[RT (inst)];
  627.         break;
  628.           }
  629.  
  630.         case Y_SLT_OP:
  631.           if (R[RS (inst)] < R[RT (inst)])
  632.         R[RD (inst)] = 1;
  633.           else
  634.         R[RD (inst)] = 0;
  635.           break;
  636.  
  637.         case Y_SLTI_OP:
  638.           if (R[RS (inst)] < (short) IMM (inst))
  639.         R[RT (inst)] = 1;
  640.           else
  641.         R[RT (inst)] = 0;
  642.           break;
  643.  
  644.         case Y_SLTIU_OP:
  645.           {
  646.         int x = (short) IMM (inst);
  647.  
  648.         if ((unsigned long) R[RS (inst)] < (unsigned long) x)
  649.           R[RT (inst)] = 1;
  650.         else
  651.           R[RT (inst)] = 0;
  652.         break;
  653.           }
  654.  
  655.         case Y_SLTU_OP:
  656.           if ((unsigned long) R[RS (inst)] < (unsigned long) R[RT (inst)])
  657.         R[RD (inst)] = 1;
  658.           else
  659.         R[RD (inst)] = 0;
  660.           break;
  661.  
  662.         case Y_SRA_OP:
  663.           {
  664.         int shamt = SHAMT (inst);
  665.         long val = R[RT (inst)];
  666.  
  667.         if (shamt >= 0 && shamt < 32)
  668.           R[RD (inst)] = val >> shamt;
  669.         else
  670.           R[RD (inst)] = val;
  671.         break;
  672.           }
  673.  
  674.         case Y_SRAV_OP:
  675.           {
  676.         int shamt = R[RS (inst)] & 0x1f;
  677.         long val = R[RT (inst)];
  678.  
  679.         if (shamt >= 0 && shamt < 32)
  680.           R[RD (inst)] = val >> shamt;
  681.         else
  682.           R[RD (inst)] = val;
  683.         break;
  684.           }
  685.  
  686.         case Y_SRL_OP:
  687.           {
  688.         int shamt = SHAMT (inst);
  689.         unsigned long val = R[RT (inst)];
  690.  
  691.         if (shamt >= 0 && shamt < 32)
  692.           R[RD (inst)] = val >> shamt;
  693.         else
  694.           R[RD (inst)] = val;
  695.         break;
  696.           }
  697.  
  698.         case Y_SRLV_OP:
  699.           {
  700.         int shamt = R[RS (inst)] & 0x1f;
  701.         unsigned long val = R[RT (inst)];
  702.  
  703.         if (shamt >= 0 && shamt < 32)
  704.           R[RD (inst)] = val >> shamt;
  705.         else
  706.           R[RD (inst)] = val;
  707.         break;
  708.           }
  709.  
  710.         case Y_SUB_OP:
  711.           {
  712.         register reg_word vs = R[RS (inst)], vt = R[RT (inst)];
  713.         register reg_word diff = vs - vt;
  714.  
  715.         if (SIGN_BIT (vs) != SIGN_BIT (vt)
  716.             && SIGN_BIT (vs) != SIGN_BIT (diff))
  717.           RAISE_EXCEPTION (OVF_EXCPT, break);
  718.         R[RD (inst)] = diff;
  719.         break;
  720.           }
  721.  
  722.         case Y_SUBU_OP:
  723.           R[RD (inst)] = (unsigned long) R[RS (inst)]
  724.         - (unsigned long) R[RT (inst)];
  725.           break;
  726.  
  727.         case Y_SW_OP:
  728.           SET_MEM_WORD (R[BASE (inst)] + IOFFSET (inst), R[RT (inst)]);
  729.           break;
  730.  
  731.         case Y_SWC0_OP:
  732.         case Y_SWC2_OP:
  733.         case Y_SWC3_OP:
  734.           SET_MEM_WORD (R[BASE (inst)] + IOFFSET (inst),
  735.                 CPR[OPCODE (inst) - Y_SWC0_OP][RT (inst)]);
  736.           break;
  737.  
  738.         case Y_SWL_OP:
  739.           {
  740.         register mem_addr addr = R[BASE (inst)] + IOFFSET (inst);
  741.         mem_word data;
  742.         reg_word reg = R[RT (inst)];
  743.         register int byte = addr & 0x3;
  744.  
  745.         READ_MEM_WORD (data, (addr & 0xfffffffc));
  746. #ifdef BIGENDIAN
  747.         switch (byte)
  748.           {
  749.           case 0:
  750.             data = reg;
  751.             break;
  752.  
  753.           case 1:
  754.             data = (data & 0xff000000) | (reg >> 8 & 0xffffff);
  755.             break;
  756.  
  757.           case 2:
  758.             data = (data & 0xffff0000) | (reg >> 16 & 0xffff);
  759.             break;
  760.  
  761.           case 3:
  762.             data = (data & 0xffffff00) | (reg >> 24 & 0xff);
  763.             break;
  764.           }
  765. #else
  766.         switch (byte)
  767.           {
  768.           case 0:
  769.             data = (data & 0xffffff00) | (reg >> 24 & 0xff);
  770.             break;
  771.  
  772.           case 1:
  773.             data = (data & 0xffff0000) | (reg >> 16 & 0xffff);
  774.             break;
  775.  
  776.           case 2:
  777.             data = (data & 0xff000000) | (reg >> 8 & 0xffffff);
  778.             break;
  779.  
  780.           case 3:
  781.             data = reg;
  782.             break;
  783.           }
  784. #endif
  785.         SET_MEM_WORD (addr & 0xfffffffc, data);
  786.         break;
  787.           }
  788.  
  789.         case Y_SWR_OP:
  790.           {
  791.         register mem_addr addr = R[BASE (inst)] + IOFFSET (inst);
  792.         mem_word data;
  793.         reg_word reg = R[RT (inst)];
  794.         register int byte = addr & 0x3;
  795.  
  796.         READ_MEM_WORD (data, (addr & 0xfffffffc));
  797. #ifdef BIGENDIAN
  798.         switch (byte)
  799.           {
  800.           case 0:
  801.             data = ((reg << 24) & 0xff000000) | (data & 0xffffff);
  802.             break;
  803.  
  804.           case 1:
  805.             data = ((reg << 16) & 0xffff0000) | (data & 0xffff);
  806.             break;
  807.  
  808.           case 2:
  809.             data = ((reg << 8) & 0xffffff00) | (data & 0xff) ;
  810.             break;
  811.  
  812.           case 3:
  813.             data = reg;
  814.             break;
  815.           }
  816. #else
  817.         switch (byte)
  818.           {
  819.           case 0:
  820.             data = reg;
  821.             break;
  822.  
  823.           case 1:
  824.             data = ((reg << 8) & 0xffffff00) | (data & 0xff) ;
  825.             break;
  826.  
  827.           case 2:
  828.             data = ((reg << 16) & 0xffff0000) | (data & 0xffff);
  829.             break;
  830.  
  831.           case 3:
  832.             data = ((reg << 24) & 0xff000000) | (data & 0xffffff);
  833.             break;
  834.           }
  835. #endif
  836.         SET_MEM_WORD (addr & 0xfffffffc, data);
  837.         break;
  838.           }
  839.  
  840.         case Y_SYSCALL_OP:
  841.           if (!do_syscall ())
  842.         return (0);
  843.           break;
  844.  
  845.         case Y_TLBP_OP:
  846.         case Y_TLBR_OP:
  847.         case Y_TLBWI_OP:
  848.         case Y_TLBWR_OP:
  849.           fatal_error ("Unimplemented operation\n");
  850.           break;
  851.  
  852.         case Y_XOR_OP:
  853.           R[RD (inst)] = R[RS (inst)] ^ R[RT (inst)];
  854.           break;
  855.  
  856.         case Y_XORI_OP:
  857.           R[RT (inst)] = R[RS (inst)] ^ (0xffff & IMM (inst));
  858.           break;
  859.  
  860.  
  861.           /* FPA Operations */
  862.  
  863.  
  864.         case Y_ABS_S_OP:
  865.           SET_FPR_S (FD (inst), fabs (FPR_S (FS (inst))));
  866.           break;
  867.  
  868.         case Y_ABS_D_OP:
  869.           SET_FPR_D (FD (inst), fabs (FPR_D (FS (inst))));
  870.           break;
  871.  
  872.         case Y_ADD_S_OP:
  873.           SET_FPR_S (FD (inst), FPR_S (FS (inst)) + FPR_S (FT (inst)));
  874.           /* Should trap on inexact/overflow/underflow */
  875.           break;
  876.  
  877.         case Y_ADD_D_OP:
  878.           SET_FPR_D (FD (inst), FPR_D (FS (inst)) + FPR_D (FT (inst)));
  879.           /* Should trap on inexact/overflow/underflow */
  880.           break;
  881.  
  882.         case Y_BC1F_OP:
  883.           BRANCH_INST (FpCond == 0,
  884.                PC + (SIGN_EX (IOFFSET (inst)) << 2));
  885.           break;
  886.  
  887.         case Y_BC1T_OP:
  888.           BRANCH_INST (FpCond == 1,
  889.                PC + (SIGN_EX (IOFFSET (inst)) << 2));
  890.           break;
  891.  
  892.         case Y_C_F_S_OP:
  893.         case Y_C_UN_S_OP:
  894.         case Y_C_EQ_S_OP:
  895.         case Y_C_UEQ_S_OP:
  896.         case Y_C_OLE_S_OP:
  897.         case Y_C_ULE_S_OP:
  898.         case Y_C_SF_S_OP:
  899.         case Y_C_NGLE_S_OP:
  900.         case Y_C_SEQ_S_OP:
  901.         case Y_C_NGL_S_OP:
  902.         case Y_C_LT_S_OP:
  903.         case Y_C_NGE_S_OP:
  904.         case Y_C_LE_S_OP:
  905.         case Y_C_NGT_S_OP:
  906.           {
  907.         float v1 = FPR_S (FS (inst)), v2 = FPR_S (FT (inst));
  908.         double dv1 = v1, dv2 = v2;
  909.         int less, equal, unordered;
  910.         int cond = COND (inst);
  911.  
  912.         if (NaN (dv1) || NaN (dv2))
  913.           {
  914.             less = 0;
  915.             equal = 0;
  916.             unordered = 1;
  917.             if (cond & COND_IN)
  918.               RAISE_EXCEPTION (INVALID_EXCEPT, break);
  919.           }
  920.         else
  921.           {
  922.             less = v1 < v2;
  923.             equal = v1 == v2;
  924.             unordered = 0;
  925.           }
  926.         FpCond = 0;
  927.         if (cond & COND_LT)
  928.           FpCond |= less;
  929.         if (cond & COND_EQ)
  930.           FpCond |= equal;
  931.         if (cond & COND_UN)
  932.           FpCond |= unordered;
  933.           }
  934.           break;
  935.  
  936.         case Y_C_F_D_OP:
  937.         case Y_C_UN_D_OP:
  938.         case Y_C_EQ_D_OP:
  939.         case Y_C_UEQ_D_OP:
  940.         case Y_C_OLE_D_OP:
  941.         case Y_C_ULE_D_OP:
  942.         case Y_C_SF_D_OP:
  943.         case Y_C_NGLE_D_OP:
  944.         case Y_C_SEQ_D_OP:
  945.         case Y_C_NGL_D_OP:
  946.         case Y_C_LT_D_OP:
  947.         case Y_C_NGE_D_OP:
  948.         case Y_C_LE_D_OP:
  949.         case Y_C_NGT_D_OP:
  950.           {
  951.         double v1 = FPR_D (FS (inst)), v2 = FPR_D (FT (inst));
  952.         int less, equal, unordered;
  953.         int cond = COND (inst);
  954.  
  955.         if (NaN (v1) || NaN (v2))
  956.           {
  957.             less = 0;
  958.             equal = 0;
  959.             unordered = 1;
  960.             if (cond & COND_IN)
  961.               RAISE_EXCEPTION (INVALID_EXCEPT, break);
  962.           }
  963.         else
  964.           {
  965.             less = v1 < v2;
  966.             equal = v1 == v2;
  967.             unordered = 0;
  968.           }
  969.         FpCond = 0;
  970.         if (cond & COND_LT)
  971.           FpCond |= less;
  972.         if (cond & COND_EQ)
  973.           FpCond |= equal;
  974.         if (cond & COND_UN)
  975.           FpCond |= unordered;
  976.           }
  977.           break;
  978.  
  979.         case Y_CFC1_OP:
  980.           R[RT (inst)] = FCR[RD (inst)]; /* RD not FS */
  981.           break;
  982.  
  983.         case Y_CTC1_OP:
  984.           FCR[RD (inst)] = R[RT (inst)]; /* RD not FS */
  985.           break;
  986.  
  987.         case Y_CVT_D_S_OP:
  988.           {
  989.         double val = FPR_S (FS (inst));
  990.  
  991.         SET_FPR_D (FD (inst), val);
  992.         break;
  993.           }
  994.  
  995.         case Y_CVT_D_W_OP:
  996.           {
  997.         double val = FPR_W (FS (inst));
  998.  
  999.         SET_FPR_D (FD (inst), val);
  1000.         break;
  1001.           }
  1002.  
  1003.         case Y_CVT_S_D_OP:
  1004.           {
  1005.         float val = FPR_D (FS (inst));
  1006.  
  1007.         SET_FPR_S (FD (inst), val);
  1008.         break;
  1009.           }
  1010.  
  1011.         case Y_CVT_S_W_OP:
  1012.           {
  1013.         float val = FPR_W (FS (inst));
  1014.  
  1015.         SET_FPR_S (FD (inst), val);
  1016.         break;
  1017.           }
  1018.  
  1019.         case Y_CVT_W_D_OP:
  1020.           {
  1021.         int val = FPR_D (FS (inst));
  1022.  
  1023.         SET_FPR_W (FD (inst), val);
  1024.         break;
  1025.           }
  1026.  
  1027.         case Y_CVT_W_S_OP:
  1028.           {
  1029.         int val = FPR_S (FS (inst));
  1030.  
  1031.         SET_FPR_W (FD (inst), val);
  1032.         break;
  1033.           }
  1034.  
  1035.         case Y_DIV_S_OP:
  1036.           SET_FPR_S (FD (inst), FPR_S (FS (inst)) / FPR_S (FT (inst)));
  1037.           break;
  1038.  
  1039.         case Y_DIV_D_OP:
  1040.           SET_FPR_D (FD (inst), FPR_D (FS (inst)) / FPR_D (FT (inst)));
  1041.           break;
  1042.  
  1043.         case Y_LWC1_OP:
  1044.           {
  1045.         reg_word *wp = (reg_word *) &FGR[FT (inst)];
  1046.  
  1047.         LOAD_INST (READ_MEM_WORD, R[BASE (inst)] + IOFFSET (inst), wp,
  1048.                0xffffffff);
  1049.         break;
  1050.           }
  1051.  
  1052.         case Y_MFC1_OP:
  1053.           {
  1054.         float val = FGR[RD (inst)]; /* RD not FS */
  1055.         reg_word *vp = (reg_word *) &val;
  1056.  
  1057.         R[RT (inst)] = *vp; /* Fool coercion */
  1058.         break;
  1059.           }
  1060.  
  1061.         case Y_MOV_S_OP:
  1062.           SET_FPR_S (FD (inst), FPR_S (FS (inst)));
  1063.           break;
  1064.  
  1065.         case Y_MOV_D_OP:
  1066.           SET_FPR_D (FD (inst), FPR_D (FS (inst)));
  1067.           break;
  1068.  
  1069.         case Y_MTC1_OP:
  1070.           {
  1071.         reg_word word = R[RT (inst)];
  1072.         float *wp = (float *) &word;
  1073.  
  1074.         FGR[RD (inst)] = *wp; /* RD not FS, fool coercion */
  1075.         break;
  1076.           }
  1077.  
  1078.         case Y_MUL_S_OP:
  1079.           SET_FPR_S (FD (inst), FPR_S (FS (inst)) * FPR_S (FT (inst)));
  1080.           break;
  1081.  
  1082.         case Y_MUL_D_OP:
  1083.           SET_FPR_D (FD (inst), FPR_D (FS (inst)) * FPR_D (FT (inst)));
  1084.           break;
  1085.  
  1086.         case Y_NEG_S_OP:
  1087.           SET_FPR_S (FD (inst), -FPR_S (FS (inst)));
  1088.           break;
  1089.  
  1090.         case Y_NEG_D_OP:
  1091.           SET_FPR_D (FD (inst), -FPR_D (FS (inst)));
  1092.           break;
  1093.  
  1094.         case Y_SUB_S_OP:
  1095.           SET_FPR_S (FD (inst), FPR_S (FS (inst)) - FPR_S (FT (inst)));
  1096.           break;
  1097.  
  1098.         case Y_SUB_D_OP:
  1099.           SET_FPR_D (FD (inst), FPR_D (FS (inst)) - FPR_D (FT (inst)));
  1100.           break;
  1101.  
  1102.         case Y_SWC1_OP:
  1103.           {
  1104.         float val = FGR[RT (inst)];
  1105.         reg_word *vp = (reg_word *) &val;
  1106.  
  1107.         SET_MEM_WORD (R[BASE (inst)] + IOFFSET (inst), *vp);
  1108.         break;
  1109.           }
  1110.  
  1111.         default:
  1112.           fatal_error ("Unknown instruction type: %d\n", OPCODE (inst));
  1113.           break;
  1114.         }
  1115.  
  1116.       /* After instruction executes: */
  1117.       PC += BYTES_PER_WORD;
  1118.  
  1119.       if (exception_occurred)
  1120.         {
  1121.           if ((Cause >> 2) > LAST_REAL_EXCEPT)
  1122.         EPC = PC - BYTES_PER_WORD;
  1123.  
  1124.           handle_exception ();
  1125.         }
  1126.     }            /* End: for (step = 0; ... */
  1127.     }                /* End: for ( ; steps_to_run > 0 ... */
  1128.  
  1129.   /* Executed enought steps, return, but are able to continue. */
  1130.   return (1);
  1131. }
  1132.  
  1133.  
  1134. /* Multiply two 32-bit numbers, V1 and V2, to produce a 64 bit result in
  1135.    the HI/LO registers.     The algorithm is high-school math:
  1136.  
  1137.      A B
  1138.        x C D
  1139.        ------
  1140.        AD || BD
  1141.  AC || CB || 0
  1142.  
  1143.  where A and B are the high and low short words of V1, C and D are the short
  1144.  words of V2, AD is the product of A and D, and X || Y is (X << 16) + Y.
  1145.  Since the algorithm is programmed in C, we need to be careful not to
  1146.  overflow. */
  1147.  
  1148. #ifdef __STDC__
  1149. static void
  1150. long_multiply (reg_word v1, reg_word v2)
  1151. #else
  1152. static void
  1153. long_multiply (v1, v2)
  1154.      reg_word v1, v2;
  1155. #endif
  1156. {
  1157.   register unsigned long a, b, c, d;
  1158.   register unsigned long bd, ad, cb, ac;
  1159.   register unsigned long mid, mid2, carry_mid = 0;
  1160.  
  1161.   a = (v1 >> 16) & 0xffff;
  1162.   b = v1 & 0xffff;
  1163.   c = (v2 >> 16) & 0xffff;
  1164.   d = v2 & 0xffff;
  1165.  
  1166.   bd = b * d;
  1167.   ad = a * d;
  1168.   cb = c * b;
  1169.   ac = a * c;
  1170.  
  1171.   mid = ad + cb;
  1172.   if (mid < ad || mid < cb)
  1173.     /* Arithmetic overflow or carry-out */
  1174.     carry_mid = 1;
  1175.  
  1176.   mid2 = mid + ((bd >> 16) & 0xffff);
  1177.   if (mid2 < mid || mid2 < ((bd >> 16) & 0xffff))
  1178.     /* Arithmetic overflow or carry-out */
  1179.     carry_mid += 1;
  1180.  
  1181.   LO = (bd & 0xffff) | ((mid2 & 0xffff) << 16);
  1182.   HI = ac + (carry_mid << 16) + ((mid2 >> 16) & 0xffff);
  1183. }
  1184.